package com.yunc.modules.generator.controller;

import com.baomidou.mybatisplus.core.toolkit.StringPool;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.generator.AutoGenerator;
import com.baomidou.mybatisplus.generator.InjectionConfig;
import com.baomidou.mybatisplus.generator.config.*;
import com.baomidou.mybatisplus.generator.config.po.TableInfo;
import com.baomidou.mybatisplus.generator.config.rules.DateType;
import com.baomidou.mybatisplus.generator.config.rules.NamingStrategy;
import com.baomidou.mybatisplus.generator.engine.FreemarkerTemplateEngine;
import com.yunc.base.controller.CommonController;
import com.yunc.common.properties.GenPro;
import com.yunc.common.utils.R;
import com.yunc.config.MybatisProperties;
import com.yunc.modules.generator.entity.dto.ColumnDTO;
import com.yunc.modules.generator.entity.dto.TableDTO;
import com.yunc.modules.generator.service.IGenService;
import org.apache.commons.lang3.StringUtils;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 数据库表
 *
 * @author congcong tao
 * @date 2019/1/28 13:36
 */
@RestController
@RequestMapping("gen")
public class GenController extends CommonController {

    private static final Logger logger = LogManager.getLogger(GenController.class);

    @Autowired(required = false)
    private GenPro genPro;
    @Autowired(required = false)
    private MybatisProperties mybatisProperties;
    @Autowired
    private IGenService genService;

    @GetMapping("/page")
    public R page(Page<TableDTO> page, TableDTO tableDTO){
        genService.pageInfo(page, tableDTO);
        return R.ok().put("data", page.getRecords()).put("count", page.getTotal());
    }

    @GetMapping("/getTableByName/{tableName}")
    public R getTableByName(@PathVariable String tableName){
        TableDTO tableInfo = genService.getByTableName(tableName);
        List<ColumnDTO> columnList = genService.getTableColumnsByName(tableName);
        // 默认实体类名称，驼峰
        String className = NamingStrategy.underlineToCamel(tableInfo.getTableName());
        tableInfo.setClassName(NamingStrategy.capitalFirst(className));
        // 取第一个下划线的
        String moduleName;
        if (StringUtils.isNotEmpty(tableInfo.getTableName())) {
            String[] split = tableInfo.getTableName().split("_");
            moduleName = split[0];
        } else {
            moduleName = genPro.getGeneratorModuleName();
        }
        // 输出文件夹
        if (StringUtils.isEmpty(genPro.getGeneratorOutputDir())) {
            String generatorOutputDir = System.getProperty("user.dir") + "/src/main/java";
            tableInfo.setOutputDir(generatorOutputDir);
        } else {
            tableInfo.setOutputDir(genPro.getGeneratorOutputDir());
        }
        if (StringUtils.isNotEmpty(genPro.getGeneratorAuthor())) {
            tableInfo.setAuthor(genPro.getGeneratorAuthor());
        }
        if (StringUtils.isNotEmpty(genPro.getGeneratorPackageInfo())) {
            tableInfo.setPackageInfo(genPro.getGeneratorPackageInfo());
        }
        tableInfo.setModuleName(moduleName);
        return R.ok().put("tableInfo", tableInfo).put("columnList", columnList);
    }

    @GetMapping("/getTableColumnsByName/{tableName}")
    public R getTableColumnsByName(@PathVariable String tableName){
        List<ColumnDTO> columnList = genService.getTableColumnsByName(tableName);
        return R.ok().put("columnList", columnList);
    }

    @PostMapping("/generate")
    public R export(@RequestBody TableDTO tableInfo){
        String projectPath = System.getProperty("user.dir");
        // 代码生成器
        AutoGenerator mpg = new AutoGenerator();
        // 全局配置
        GlobalConfig gc = new GlobalConfig();
        gc.setOutputDir(tableInfo.getOutputDir());
        gc.setAuthor(tableInfo.getAuthor());
        gc.setOpen(false);
        // 设置时间类型为Date
        gc.setDateType(DateType.ONLY_DATE);
        // gc.setIdType(IdType.AUTO);
        // 设置类名称
        gc.setEntityName(tableInfo.getClassName());
        gc.setMapperName(tableInfo.getClassName() + "Mapper");
        gc.setServiceName("I" + tableInfo.getClassName() + "Service");
        gc.setServiceImplName(tableInfo.getClassName() + "ServiceImpl");
        gc.setControllerName(tableInfo.getClassName() + "Controller");
        mpg.setGlobalConfig(gc);
        // 数据源配置
        DataSourceConfig dsc = new DataSourceConfig();
        dsc.setUrl(mybatisProperties.getUrl());
        // dsc.setSchemaName("public");
        dsc.setDriverName("com.mysql.jdbc.Dri");
        dsc.setUsername(mybatisProperties.getUsername());
        dsc.setPassword(mybatisProperties.getPassword());
        mpg.setDataSource(dsc);
        // 包配置
        PackageConfig pc = new PackageConfig();
        pc.setModuleName(tableInfo.getModuleName());
        pc.setParent(tableInfo.getPackageInfo());
        mpg.setPackageInfo(pc);
        // 自定义配置
        InjectionConfig cfg = new InjectionConfig() {
            @Override
            public void initMap() {
                // to do nothing
                Map hashMap = new HashMap(1);
                hashMap.put("entityName", StringUtils.uncapitalize(tableInfo.getClassName()));
                this.setMap(hashMap);
            }
        };
        // 模板引擎是 freemarker
        String templatePath = "/gentemplates/mapper2.xml.ftl";
        // 自定义输出配置
        List<FileOutConfig> focList = new ArrayList<>();
        // 自定义配置会被优先输出
        focList.add(new FileOutConfig(templatePath) {
            @Override
            public String outputFile(TableInfo tableInfo) {
                // 自定义输出文件名
                return projectPath + "/src/main/resources/mapper/"
                        + tableInfo.getEntityName() + "Mapper" + StringPool.DOT_XML;
            }
        });

        cfg.setFileOutConfigList(focList);
        mpg.setCfg(cfg);
        // 配置模板
        TemplateConfig templateConfig = new TemplateConfig();
        // 配置自定义输出模板
        // 指定自定义模板路径，注意不要带上.ftl/.vm, 会根据使用的模板引擎自动识别
        templateConfig.setEntity("gentemplates/entity2.java");
        templateConfig.setMapper("gentemplates/mapper2.java");
        templateConfig.setService("gentemplates/service2.java");
        templateConfig.setServiceImpl("gentemplates/serviceImpl2.java");
        templateConfig.setController("gentemplates/controller2.java");
        templateConfig.setXml(null);
        mpg.setTemplate(templateConfig);
        // 策略配置
        StrategyConfig strategy = new StrategyConfig();
        strategy.setNaming(NamingStrategy.underline_to_camel);
        strategy.setColumnNaming(NamingStrategy.underline_to_camel);
        // strategy.setSuperEntityClass("com.baomidou.ant.common.BaseEntity");
        strategy.setEntityLombokModel(true);
        strategy.setRestControllerStyle(true);
        strategy.setSuperControllerClass("com.yunc.base.controller.CommonController");
        strategy.setInclude(tableInfo.getTableName());
        strategy.setSuperEntityColumns("id");
        strategy.setSuperMapperClass("com.yunc.base.SuperMapper");
        strategy.setControllerMappingHyphenStyle(true);
        strategy.setTablePrefix(pc.getModuleName() + "_");
        mpg.setStrategy(strategy);
        mpg.setTemplateEngine(new FreemarkerTemplateEngine());
        mpg.execute();
        return R.ok("生成成功");
    }
}
